package com.jeequan.jeepay.pay.channel.pmopay.payway;

import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrder;
import com.jeequan.jeepay.core.model.params.pmopay.PmopayNormalMchParams;
import com.jeequan.jeepay.pay.channel.pmopay.PmopayPaymentService;
import com.jeequan.jeepay.pay.model.MchAppConfigContext;
import com.jeequan.jeepay.pay.rqrs.AbstractRS;
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ;
import com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRS;
import com.jeequan.jeepay.pay.rqrs.payorder.payway.PmoApiOrderRQ;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.net.SocketTimeoutException;
import java.util.UUID;

/**
 * Paymob Api放款
 */
@Slf4j
@Service
public class PaymobPayoutApi extends PmopayPaymentService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private PaymobPayoutTokenService paymobPayoutTokenService;

    @Override
    public String preCheck(UnifiedOrderRQ bizRQ, PayOrder payOrder) {
        return null;
    }

    @Override
    public AbstractRS pay(UnifiedOrderRQ bizRQ, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
        PmoApiOrderRQ orderRQ = (PmoApiOrderRQ) bizRQ;

        UnifiedOrderRS orderRS = new UnifiedOrderRS();
        orderRS.setMchOrderNo(payOrder.getMchOrderNo());
        orderRS.setPayOrderId(orderRS.getPayOrderId());
        orderRS.setMchOrderNo(orderRS.getMchOrderNo());
        orderRS.setOrderState(PayOrder.STATE_INIT);

        ChannelRetMsg channelRetMsg = new ChannelRetMsg();
        orderRS.setChannelRetMsg(channelRetMsg);

        PmopayNormalMchParams config = (PmopayNormalMchParams) mchAppConfigContext.getNormalMchParamsByIfCode(CS.IF_CODE.PMOPAY);
        String accessToken = paymobPayoutTokenService.getToken(config);
        StringBuilder sb = new StringBuilder(config.getDomain());
        sb.append("/api/secure/disburse/");

        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
        headers.add("Authorization", String.format("Bearer %s", accessToken));
        PayoutRequestParams params = PayoutRequestParams.builder()
                .issuer(orderRQ.getIssuer())
                .msisdn(orderRQ.getMsisdn())
                .amount(BigDecimal.valueOf(bizRQ.getAmount() / 100).setScale(2, BigDecimal.ROUND_HALF_UP))
                .first_name(orderRQ.getFirstName())
                .full_name(orderRQ.getFullName())
                .last_name(orderRQ.getLastName())
                .bank_code(orderRQ.getBankCode())
                .bank_card_number(orderRQ.getBankCardNumber())
                .bank_transaction_type(orderRQ.getBankTransactionType())
                .email(orderRQ.getEmail())
                .client_reference_id(UUID.randomUUID().toString().replaceAll("-", ""))
                .build();
        String body = JSONObject.toJSONString(params);
        HttpEntity<String> httpEntity = new HttpEntity<>(body, headers);

        try {
            ResponseEntity<String> responseEntity = restTemplate.exchange(sb.toString(), HttpMethod.POST, httpEntity, String.class);
            log.info("响应状态：{}，响应结果：{}", responseEntity.getStatusCodeValue(), responseEntity.getBody());
            if (responseEntity.getStatusCode().is2xxSuccessful()) {
                JSONObject result = JSONObject.parseObject(responseEntity.getBody());
                String statusCode = result.getString("status_code");
                channelRetMsg.setChannelOrderId(result.getString("transaction_id"));
                channelRetMsg.setChannelOriginResponse(responseEntity.getBody());
                channelRetMsg.setResponseEntity(ResponseEntity.ok().body(result.getString("disbursement_status")));
                channelRetMsg.setNeedQuery(true);
                // 标记订单状态：支付中
                orderRS.setOrderState(PayOrder.STATE_ING);
                if ("200".equals(statusCode) || "8000".equals(statusCode)) {
                    // 被明确告知下单成功,支付中
                    channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);

                } else if ("90040".equals(statusCode)) {
                    // 被明确告知下单失败
                    channelRetMsg.setChannelErrCode(statusCode);
                    channelRetMsg.setChannelErrMsg(result.getString("disbursement_status"));
                    orderRS.setErrCode(statusCode);
                    orderRS.setErrMsg(channelRetMsg.getChannelErrMsg());
                    channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
                } else {
                    // 下单状态未知
                    channelRetMsg.setChannelErrCode(statusCode);
                    channelRetMsg.setChannelErrMsg(result.getString("disbursement_status"));
                    orderRS.setErrCode(statusCode);
                    orderRS.setErrMsg(channelRetMsg.getChannelErrMsg());
                    channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.UNKNOWN);
                }
            }
        } catch (Exception ex) {
            if (ex.getClass().isInstance(SocketTimeoutException.class)) {
                channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.UNKNOWN);
            } else {
                channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
            }
            log.error("创建放款订单异常", ex);
        }

        return orderRS;
    }


}
